#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdio_ext.h>
#include <stdlib.h>
#include <termios.h> 
#include <signal.h> 

#include "input_judge.h"

/**
 * @brief   获取输入
 * @param   str:指向装载输入的字符串的指针。
 * @return  错误返回错误信息
 */
int get_str_input(char *input)
{
    int length;

    if (!input) {
        return -1;
    }

    length = INPUT_LENGTH;
    memset(input, '\0', length);

    fgets(input, length, stdin);
    __fpurge(stdin);
    if (input[strlen(input) - 1] == '\n')
        input[strlen(input) - 1] = '\0';
    
    return 0;
}

/**
 * @brief   判断字符串是否为 大小写字母或数字。
 * @param   str：指向字符串的指针（字符串一般是通过get_str_input();得到的输入）。
 * @return  符合返回——1 不符合返回——0 错误返回错误信息
 */
int is_num_or_char(char *str)
{
    uint8_t count;
    uint8_t ret;

    if (!str) {
        return -1;
    }

    for (count = 0; count < INPUT_LENGTH; count++) {

        if (str[count] == '\0')
            break;
        if ((str[count] >= '0' && str[count] <= '9') ||
            (str[count] >= 'A' && str[count] <= 'Z') ||
            (str[count] >= 'a' && str[count] <= 'z'))
            ret = TRUE;
        else
            return FALSE;
    }
    return ret;
}

/**
 * @brief   判断字符串是否y，Y，n，N。
 * @param   str:指向字符串的指针(字符串一般是通过get_str_input();得到的输入)。
 * @return  符合返回——1 不符合返回——0 错误返回错误信息
 */
int is_y_or_n(char *str)
{
    uint8_t length;
    char input;

    if (!str) {
        return -1;
    }

    length = strlen(str);
    if (length != 1)
        return FALSE;

    input = str[0];
    if (input == 'y' ||
       input == 'Y' ||
       input == 'n' ||
       input == 'N')
        return TRUE;
    else
        return FALSE;
}

/**
 * @brief   判断字符串是否车票id(第一个是大写字母，后面接4个数字，eg：D1234).
 * @param   str:指向字符串的指针(字符串一般是通过get_str_input();得到的输入)。
 * @return  符合返回——1 不符合返回——0 错误返回错误信息
 */
int is_ticket_id(char *str)
{
    uint8_t length;
    uint8_t count;

    if (!str) {
        return -1;
    }

    length = strlen(str);
    if (length != 5)
        return FALSE;
    
    if (str[0] >= 'a' && str[0] <= 'z') {
        for (count = 1; count < 5 ; count++) {
            if (str[count] < '0' || str[count] > '9')
                return FALSE;
        }
        return TRUE;
    } else
        return FALSE;
}

/**
 * @brief   判断字符串是否为纯数字。
 * @param   str：指向字符串的指针（字符串一般是通过get_str_input();得到的输入）。
 * @return  符合返回——1 不符合返回——0 错误返回错误信息
 */
int is_num(char *str)
{
    uint8_t count;

    if (!str) {
        return -1;
    }

    for (count = 0; count < INPUT_LENGTH; count++) {

        if (str[count] == '\0')
            break;
        if (str[count] < '0' || str[count] > '9')
            return FALSE;
    }
    return TRUE;
}

/**
 * @brief   判断字符串是否为大小写字母。
 * @param   str：指向字符串的指针（字符串一般是通过get_str_input();得到的输入）。
 * @return  符合返回——1 不符合返回——0 错误返回错误信息
 */
int is_string(char *str)
{
    uint8_t count;
    uint8_t ret;

    if (!str) {
        return -1;
    }

    for (count = 0; count < INPUT_LENGTH; count++) {

        if (str[count] == '\0')
            break;
        if ((str[count] >= 'A' && str[count] <= 'Z') ||
            (str[count] >= 'a' && str[count] <= 'z'))
            ret = TRUE;
        else
            return FALSE;
    }
    return ret;
}

/**
 * @brief   判断字符串是否为单个字符
 * @param   str:指向字符串的指针(字符串一般是通过get_str_input();得到的输入)。
 * @return  符合返回——1 不符合返回——0 错误返回错误信息
 */
int is_sigal_char(char *str)
{
    uint8_t length;
    char input;

    if (!str) {
        return -1;
    }

    length = strlen(str);
    if (length != 1)
        return FALSE;

    input = str[0];
    if ((input >= 'a' && input <= 'z') || 
        (input >= 'A' && input <= 'Z') || 
        (input >= '0' && input <= '9'))
        return TRUE;
    else
        return FALSE;
}

/**
 * @brief   判断字符串是否功能字符。
 *          m/M 返回主菜单  r/R 返回上一层  q/Q 退出。
 * @param   str:指向字符串的指针(字符串一般是通过get_str_input();得到的输入)。
 * @return  符合返回——1 不符合返回——0 错误返回错误信息
 */
int is_function(char *str)
{
    uint8_t length;
    char input;

    if (!str) {
        return -1;
    }

    length = strlen(str);
    if (length != 1)
        return FALSE;

    input = str[0];
    if (input == 'm' ||
        input == 'M' ||
        input == 'r' ||
        input == 'R' ||
        input == 'q' ||
        input == 'Q')
        return TRUE;
    else
        return FALSE;
}

int is_chinese(char *str)
{
    int count;
    uint8_t length;

    if (!str) {
        return -1;
    }

    length = strlen(str);

    for (count = 0; count < length; count++) {
        if (str[count] == '\0')
            break;

        if ((unsigned char)str[count] < 128)
            return FALSE;
    }

    return TRUE;
}

int is_time(char *str)
{
    int count;
    char time[3];
    uint8_t length;

    if (!str) {
        return -1;
    }

    length = strlen(str);

    for (count = 0; count <length; count++) {
        if (str[2] == ':') {
            if (str[count] < '0' && str[count] > '9')
                return FALSE;
        } else
            return FALSE;
    }

    time[0] = str[0];
    time[1] = str[1];
    time[2] = '\0';
    if (atoi(time) > 23)
        return FALSE;

    time[0] = str[3];
    time[1] = str[4];
    time[2] = str[5];
    if (atoi(time) > 59)
        return FALSE;

    return TRUE;

}
/*模拟实现getch*/
int getch(void)
{
    struct termios temp_setting, old_setting;
    int ch;

    if (tcgetattr(fileno(stdin), &temp_setting) < 0) {
        return -1;
    }

    old_setting = temp_setting;
    cfmakeraw(&temp_setting);
    if (tcsetattr(fileno(stdin), TCSANOW, &temp_setting) < 0) {
        return -1;
    }
    ch = getchar();
    if (tcsetattr(fileno(stdin), TCSANOW, &old_setting) < 0) {
        return -1;
    }

    return ch;
}

/*直接获取按键输入，不需要按回车*/
int get_input(void)
{
	int input_char;
	int input_option = INPUT_NONE;

	input_char = getch();
	if(input_char == 27) {

        input_char = getch();
		if(input_char  == 91) {
			input_char = getch();
			switch (input_char) {
				case INPUT_UP:
					input_option = INPUT_UP;
					break;

				case INPUT_DOWN: 
					input_option = INPUT_DOWN;
					break;

				case INPUT_RIGHT: 
					input_option = INPUT_RIGHT;
					break;

				case INPUT_LEFT: 
					input_option = INPUT_LEFT;
					break;

				default :  
					input_option =  INPUT_NONE;
                    break;
			}
		}
	} else if (input_char == 13)
		input_option =  INPUT_ENTER;
	else if (input_char == 127)//8
		input_option =  INPUT_BACKSPACE;
    else if (input_char == 3) {
        raise(SIGINT);
    } else
        input_option = input_char;

	return input_option;
}

